﻿Namespace Commanding
    Public Class ConstructorCommand
        Inherits ResultCommand

        Public Shared ReadOnly ObjectTypeProperty As DependencyProperty = DependencyProperty.Register("ObjectType", GetType(Type), GetType(ConstructorCommand))
        Public Property ObjectType As Type
            Get
                Return GetValue(ObjectTypeProperty)
            End Get
            Set(ByVal value As Type)
                SetValue(ObjectTypeProperty, value)
            End Set
        End Property

        Public Shared ReadOnly CanExecuteFuncProperty As DependencyProperty = DependencyProperty.Register("CanExecuteFunc", GetType(Func(Of Boolean)), GetType(ConstructorCommand))
        Public Property CanExecuteFunc As Func(Of Boolean)
            Get
                Return GetValue(CanExecuteFuncProperty)
            End Get
            Set(ByVal value As Func(Of Boolean))
                SetValue(CanExecuteFuncProperty, value)
            End Set
        End Property

        Protected Overrides ReadOnly Property SupportsCanExecute As Boolean
            Get
                Return (CanExecuteFunc IsNot Nothing)
            End Get
        End Property

        Protected Overrides Function CreateInstanceCore() As System.Windows.Freezable
            Return New ConstructorCommand
        End Function

        Public Overrides Sub Execute(ByVal parameter As Object)
            If ObjectType IsNot Nothing Then
                Result = Activator.CreateInstance(ObjectType)
            End If
        End Sub

        Public Overrides Function CanExecute(ByVal parameter As Object) As Boolean
            Dim result As Boolean = False
            If ObjectType IsNot Nothing Then
                If CanExecuteFunc Is Nothing Then
                    result = True
                Else
                    Try
                        result = CanExecuteFunc.Invoke()
                    Finally
                    End Try
                End If
            End If
            Return result
        End Function

    End Class

    Public Class ConstructorCommand(Of T)
        Inherits ResultCommand

        Public Shared ReadOnly ObjectTypeProperty As DependencyProperty = DependencyProperty.Register("ObjectType", GetType(Type), GetType(ConstructorCommand))
        Public Property ObjectType As Type
            Get
                Return GetValue(ObjectTypeProperty)
            End Get
            Set(ByVal value As Type)
                SetValue(ObjectTypeProperty, value)
            End Set
        End Property

        Public Shared ReadOnly CanExecuteFuncProperty As DependencyProperty = DependencyProperty.Register("CanExecuteFunc", GetType(Func(Of T, Boolean)), GetType(ConstructorCommand(Of T)))
        Public Property CanExecuteFunc As Func(Of T, Boolean)
            Get
                Return GetValue(CanExecuteFuncProperty)
            End Get
            Set(ByVal value As Func(Of T, Boolean))
                SetValue(CanExecuteFuncProperty, value)
            End Set
        End Property

        Protected Overrides ReadOnly Property SupportsCanExecute As Boolean
            Get
                Return (CanExecuteFunc IsNot Nothing)
            End Get
        End Property

        Protected Overrides Function CreateInstanceCore() As System.Windows.Freezable
            Return New ConstructorCommand(Of T)
        End Function

        Public Overrides Sub Execute(ByVal sender As Object, ByVal parameter As Object)
            Dim p As T = CType(parameter, T)
            If ObjectType IsNot Nothing Then
                Result = Activator.CreateInstance(ObjectType, p)
            End If
        End Sub

        Public Overrides Function CanExecute(ByVal sender As Object, ByVal parameter As Object) As Boolean
            Dim result As Boolean = False
            Dim p As T = CType(parameter, T)
            If ObjectType IsNot Nothing Then
                If CanExecuteFunc Is Nothing Then
                    result = True
                Else
                    Try
                        result = CanExecuteFunc.Invoke(p)
                    Finally
                    End Try
                End If
            End If
            Return result
        End Function

    End Class

    Public Class ConstructorCommandOfObject
        Inherits ConstructorCommand(Of Object)

        Protected Overrides Function CreateInstanceCore() As System.Windows.Freezable
            Return New ConstructorCommandOfObject
        End Function
    End Class
End Namespace